package pers.lmd.common.exception;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.exception.NotPermissionException;
import cn.dev33.satoken.exception.NotRoleException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import pers.lmd.common.constant.ResultEnum;
import pers.lmd.common.utils.ResultUtil;
import pers.lmd.domain.R;

/**
 * 全局异常处理
 *
 * @author lmd
 */
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {


    /**
     * 未登录
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = NotLoginException.class)
    public R<ServiceError> notLoginExceptionHandler(NotLoginException e) {
        errorFixedPosition(e);
        log.error("_> 错误原因：");
        log.error("_> {}", e.getMessage());
        log.error("=============================错误打印完毕=============================");
        return ResultUtil.error(ResultEnum.NO_LOGIN_ERROR);
    }

    /**
     * 角色异常
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value = {NotRoleException.class, NotPermissionException.class})
    public R<ServiceError> notRoleExceptionHandler(Exception e) {
        errorFixedPosition(e);
        log.error("_> 错误原因：");
        log.error("_> {}", e.getMessage());
        log.error("=============================错误打印完毕=============================");
        return ResultUtil.error(ResultEnum.NO_PERMISSION_ERROR);
    }


    // @ExceptionHandler(value = ConstraintViolationException.class)
    // public Result<List<String>> constraintViolationHandler(ConstraintViolationException e) {
	// 	Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
	// 	LinkedList<String> errors = Lists.newLinkedList();
	// 	if (!CollectionUtils.isEmpty(violations)) {
	// 		violations.forEach(constraintViolation -> errors.add(constraintViolation.getMessage()));
	// 	}
    //
	// 	errorFixedPosition(e);
	// 	log.error("_> 错误原因：");
	// 	log.error("_> {}", e.getMessage());
	// 	log.error("=============================错误打印完毕=============================");
	// 	return Result.fail(BusinessErrorCode.ARGS_VALID_ERROR.getCode(), BusinessErrorCode.ARGS_VALID_ERROR.getErrMessage(), errors);
    // }

    // @ExceptionHandler(value = MethodArgumentNotValidException.class)
    // public Result<List<String>> methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException e) {
	// 	List<ObjectError> allErrors = e.getBindingResult().getAllErrors();
	// 	LinkedList<String> errors = Lists.newLinkedList();
	// 	if (!CollectionUtils.isEmpty(allErrors)) {
	// 		allErrors.forEach(objectError -> errors.add(objectError.getDefaultMessage()));
	// 	}
    //
	// 	errorFixedPosition(e);
	// 	log.error("_> 错误原因：");
	// 	log.error("_> {}", e.getMessage());
	// 	log.error("=============================错误打印完毕=============================");
	// 	return Result.fail(BusinessErrorCode.ARGS_VALID_ERROR.getCode(), BusinessErrorCode.ARGS_VALID_ERROR.getErrMessage(), errors);
    // }

    /**
     * 处理空指针的异常
     *
     * @param e 参数
     * @return 返回异常信息
     */
    // @ExceptionHandler(value = NullPointerException.class)
    // public Result<ServiceError> exceptionHandler(NullPointerException e) {
	// 	errorFixedPosition(e);
	// 	log.error("_> 错误原因：");
	// 	log.error("_> {}", e.getMessage());
	// 	log.error("=============================错误打印完毕=============================");
	// 	return Result.fail(BusinessErrorCode.SYS_ERROR);
    // }

    /**
     * 处理其他异常
     *
     * @param e 参数
     * @return 返回异常信息
     */
    // @ExceptionHandler(value = Exception.class)
    // public Result<ServiceError> exceptionHandler(Exception e) {
	// 	errorFixedPosition(e);
	// 	log.error("_> 错误原因：");
	// 	log.error("_> {}", e.getMessage());
	// 	log.error("=============================错误打印完毕=============================");
	// 	return Result.fail(BusinessErrorCode.SYS_ERROR);
    // }

    /**
     * 定位错误发生的位置
     *
     * @param e 错误参数
     */
    private void errorFixedPosition(Exception e) {
        final StackTraceElement stackTrace = e.getStackTrace()[0];
        final String className = stackTrace.getClassName();
        final int lineNumber = stackTrace.getLineNumber();
        final String methodName = stackTrace.getMethodName();
        e.printStackTrace();
        log.error("=============================错误信息如下=============================");
        log.error("_> 异常定位：");
        log.error("_> 类[{}] ==> 方法[{}] ==> 所在行[{}]\n", className, methodName, lineNumber);
    }
}
